home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / gnu / gas / src138.zoo / i386.c < prev    next >
C/C++ Source or Header  |  1991-01-21  |  61KB  |  1,936 lines

  1. /* i386.c -- Assemble code for the Intel 80386
  2.    Copyright (C) 1989, Free Software Foundation.
  3.  
  4. This file is part of GAS, the GNU Assembler.
  5.  
  6. GAS is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 1, or (at your option)
  9. any later version.
  10.  
  11. GAS is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with GAS; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.    
  20. /*
  21.   Intel 80386 machine specific gas.
  22.   Written by Eliot Dresselhaus (eliot@mgm.mit.edu).
  23.   Bugs & suggestions are completely welcome.  This is free software.
  24.   Please help us make it better.
  25. */
  26.  
  27. #include <stdio.h>
  28. #include <varargs.h>
  29. #include <ctype.h>
  30.  
  31. #ifdef __GNUC__
  32. #define alloca __builtin_alloca
  33. #else
  34. extern char *alloca();
  35. #endif
  36. #ifdef USG
  37. #define index strchr
  38. #endif
  39.  
  40. #include "as.h"
  41. #include "read.h"
  42. #include "flonum.h"
  43. #include "obstack.h"
  44. #include "frags.h"
  45. #include "struc-symbol.h"
  46. #include "expr.h"
  47. #include "symbols.h"
  48. #include "hash.h"
  49. #include "md.h"
  50. #include "i386.h"
  51. #include "i386-opcode.h"
  52.  
  53. long omagic = OMAGIC;
  54. char FLT_CHARS[] = "fFdDxX";
  55. char EXP_CHARS[] = "eE";
  56. char line_comment_chars[] = "#";
  57. char comment_chars[] = "#/";
  58.  
  59. /* tables for lexical analysis */
  60. static char opcode_chars[256];
  61. static char register_chars[256];
  62. static char operand_chars[256];
  63. static char space_chars[256];
  64. static char identifier_chars[256];
  65. static char digit_chars[256];
  66.  
  67. /* lexical macros */
  68. #define is_opcode_char(x) (opcode_chars[(unsigned char) x])
  69. #define is_operand_char(x) (operand_chars[(unsigned char) x])
  70. #define is_register_char(x) (register_chars[(unsigned char) x])
  71. #define is_space_char(x) (space_chars[(unsigned char) x])
  72. #define is_identifier_char(x) (identifier_chars[(unsigned char) x])
  73. #define is_digit_char(x) (digit_chars[(unsigned char) x])
  74.  
  75. /* put here all non-digit non-letter charcters that may occur in an operand */
  76. static char operand_special_chars[] = "%$-+(,)*._~/<>|&^!:";
  77.  
  78. static char *ordinal_names[] = { "first", "second", "third" };    /* for printfs */
  79.  
  80. /* md_assemble() always leaves the strings it's passed unaltered.  To
  81.    effect this we maintain a stack of saved characters that we've smashed
  82.    with '\0's (indicating end of strings for various sub-fields of the
  83.    assembler instruction). */
  84. static char save_stack[32];
  85. static char *save_stack_p;    /* stack pointer */
  86. #define END_STRING_AND_SAVE(s)      *save_stack_p++ = *s; *s = '\0'
  87. #define RESTORE_END_STRING(s)       *s = *--save_stack_p
  88.  
  89. /* The instruction we're assembling. */
  90. static i386_insn i;
  91.  
  92. /* Per instruction expressionS buffers: 2 displacements & 2 immediate max. */
  93. static expressionS disp_expressions[2], im_expressions[2];
  94.  
  95. /* pointers to ebp & esp entries in reg_hash hash table */
  96. static reg_entry *ebp, *esp;
  97.  
  98. static int this_operand;    /* current operand we are working on */
  99.  
  100. /*
  101. Interface to relax_segment.
  102. There are 2 relax states for 386 jump insns: one for conditional & one
  103. for unconditional jumps.  This is because the these two types of jumps
  104. add different sizes to frags when we're figuring out what sort of jump
  105. to choose to reach a given label.  */
  106.  
  107. /* types */
  108. #define COND_JUMP 1        /* conditional jump */
  109. #define UNCOND_JUMP 2        /* unconditional jump */
  110. /* sizes */
  111. #define BYTE 0
  112. #define WORD 1
  113. #define DWORD 2
  114. #define UNKNOWN_SIZE 3
  115.  
  116. #define ENCODE_RELAX_STATE(type,size) ((type<<2) | (size))
  117. #define SIZE_FROM_RELAX_STATE(s) \
  118.   ( (((s) & 0x3) == BYTE ? 1 : (((s) & 0x3) == WORD ? 2 : 4)) )
  119.  
  120. const relax_typeS md_relax_table[] = {
  121. /*
  122.   The fields are:
  123.    1) most positive reach of this state,
  124.    2) most negative reach of this state,
  125.    3) how many bytes this mode will add to the size of the current frag
  126.    4) which index into the table to try if we can't fit into this one.
  127. */
  128.   {1, 1, 0, 0},
  129.   {1, 1, 0, 0},
  130.   {1, 1, 0, 0},
  131.   {1, 1, 0, 0},
  132.  
  133.   /* For now we don't use word displacement jumps:  they may be
  134.      untrustworthy. */
  135.   {127+1, -128+1, 0, ENCODE_RELAX_STATE(COND_JUMP,DWORD) },
  136.   /* word conditionals add 3 bytes to frag:
  137.          2 opcode prefix; 1 displacement bytes */
  138.   {32767+2, -32768+2, 3, ENCODE_RELAX_STATE(COND_JUMP,DWORD) },
  139.   /* dword conditionals adds 4 bytes to frag:
  140.          1 opcode prefix; 3 displacement bytes */
  141.   {0, 0, 4, 0},
  142.   {1, 1, 0, 0},
  143.  
  144.   {127+1, -128+1, 0, ENCODE_RELAX_STATE(UNCOND_JUMP,DWORD) },
  145.   /* word jmp adds 2 bytes to frag:
  146.          1 opcode prefix; 1 displacement bytes */
  147.   {32767+2, -32768+2, 2, ENCODE_RELAX_STATE(UNCOND_JUMP,DWORD) },
  148.   /* dword jmp adds 3 bytes to frag:
  149.          0 opcode prefix; 3 displacement bytes */
  150.   {0, 0, 3, 0},
  151.   {1, 1, 0, 0},
  152.  
  153. };
  154.  
  155. void float_cons (), cons ();
  156.  
  157. /* Ignore certain directives generated by gcc. This probably should
  158.    not be here. */
  159. void dummy ()
  160. {
  161.   while (*input_line_pointer && *input_line_pointer != '\n')
  162.     input_line_pointer++;
  163. }
  164.  
  165. const pseudo_typeS md_pseudo_table[] = {
  166.     { "ffloat",    float_cons,    'f' },
  167.     { "dfloat",    float_cons,    'd' },
  168.     { "tfloat",    float_cons,    'x' },
  169.     { "value",      cons,           2 },
  170.     { "ident",      dummy,          0   }, /* ignore these directives */
  171.     { "def",        dummy,          0   },
  172.     { "optim",    dummy,        0   }, /* For sun386i cc */
  173.     { "version",    dummy,          0   },
  174.     { "ln",    dummy,          0   },
  175.     { 0, 0, 0 }
  176. };
  177.  
  178. /* for interface with expression () */
  179. extern char * input_line_pointer;
  180. char * index ();
  181.  
  182. char * output_invalid ();
  183. reg_entry * parse_register ();
  184.  
  185. /* obstack for constructing various things in md_begin */
  186. struct obstack o;
  187.  
  188. /* hash table for opcode lookup */
  189. static struct hash_control *op_hash = (struct hash_control *) 0;
  190. /* hash table for register lookup */
  191. static struct hash_control *reg_hash = (struct hash_control *) 0;
  192. /* hash table for prefix lookup */
  193. static struct hash_control *prefix_hash = (struct hash_control *) 0;
  194.  
  195.  
  196. void md_begin ()
  197. {
  198.   char * hash_err;
  199.  
  200.   obstack_begin (&o,4096);
  201.  
  202.   /* initialize op_hash hash table */
  203.   op_hash = hash_new();        /* xmalloc handles error */
  204.  
  205.   {
  206.     register template *optab;
  207.     register templates *core_optab;
  208.     char *prev_name;
  209.  
  210.     optab = i386_optab;        /* setup for loop */
  211.     prev_name = optab->name;
  212.     obstack_grow (&o, optab, sizeof(template));
  213.     core_optab = (templates *) xmalloc (sizeof (templates));
  214.  
  215.     for (optab++; optab < i386_optab_end; optab++) {
  216.       if (! strcmp (optab->name, prev_name)) {
  217.     /* same name as before --> append to current template list */
  218.     obstack_grow (&o, optab, sizeof(template));
  219.       } else {
  220.     /* different name --> ship out current template list;
  221.        add to hash table; & begin anew */
  222.     /* Note: end must be set before start! since obstack_next_free changes
  223.        upon opstack_finish */
  224.     core_optab->end = (template *) obstack_next_free(&o);
  225.     core_optab->start = (template *) obstack_finish(&o);
  226.     hash_err = hash_insert (op_hash, prev_name, (char *) core_optab);
  227.     if (hash_err && *hash_err) {
  228.     hash_error:
  229.       as_fatal("Internal Error:  Can't hash %s: %s",prev_name, hash_err);
  230.     }
  231.     prev_name = optab->name;
  232.     core_optab = (templates *) xmalloc (sizeof(templates));
  233.     obstack_grow (&o, optab, sizeof(template));
  234.       }
  235.     }
  236.   }
  237.   
  238.   /* initialize reg_hash hash table */
  239.   reg_hash = hash_new();
  240.   {
  241.     register reg_entry *regtab;
  242.  
  243.     for (regtab = i386_regtab; regtab < i386_regtab_end; regtab++) {
  244.       hash_err = hash_insert (reg_hash, regtab->reg_name, regtab);
  245.       if (hash_err && *hash_err) goto hash_error;
  246.     }
  247.   }
  248.  
  249.   esp = (reg_entry *) hash_find (reg_hash, "esp");
  250.   ebp = (reg_entry *) hash_find (reg_hash, "ebp");
  251.   
  252.   /* initialize reg_hash hash table */
  253.   prefix_hash = hash_new();
  254.   {
  255.     register prefix_entry *prefixtab;
  256.  
  257.     for (prefixtab = i386_prefixtab;
  258.      prefixtab < i386_prefixtab_end; prefixtab++) {
  259.       hash_err = hash_insert (prefix_hash, prefixtab->prefix_name, prefixtab);
  260.       if (hash_err && *hash_err) goto hash_error;
  261.     }
  262.   }
  263.  
  264.   /* fill in lexical tables:  opcode_c